package com.eureka.bclass.util;

import com.eureka.bclass.base.BaseException;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.Map;

/**
 * @Description TODO 图片加水印
 * @Author lixing
 * @Date 2020/1/3 22:09
 */
public class ImageUtil {
    /** 字体 */
    private static String FONT_FAMILY = "宋体";
    /** 字体加粗 */
    private static int FONT_STYLE = Font.BOLD;
    /** 设置水印文字的旋转角度 */
    private static Integer DEGREE = -45;
    /** 水印颜色 */
    private static Color MARKCONTENTCOLOR = Color.red;
    /** 设置水印透明度 */
    private static float ALPHA = 0.6f;

    public static void main(String[] args) throws IOException {
//        imageWatermark(
//                "Hello World!",
//                "20200721",
//                "C:\\Users\\lixing\\Desktop\\水印.png",
//                "C:\\Users\\lixing\\Desktop\\DEMO"
//        );
//        BufferedImage target = ImageIO.read(new URL("https://etiger.oss-cn-hangzhou.aliyuncs.com/d98c32146d4d4ff1bf35d8a4530141d4.JPG"));
//        zoom(target, "png", 500, 400, false);
        //
//        try {
//            // "https://etiger.oss-cn-hangzhou.aliyuncs.com/d2902f61de0f40ad9d7ab35921a0ba3f.mp4?x-oss-process=video/snapshot,t_1000,f_jpg,w_800,h_600,m_fast"
//            BufferedImage target = ImageIO.read(new File("D:\\code1.png"));
//            // "https://etiger.oss-cn-hangzhou.aliyuncs.com/module/5ca6c58bd23b0328c94f8cb4abb052c.png"
//            BufferedImage source = ImageIO.read(new File("D:\\logo2.png"));
//            Graphics2D graphics2D = target.createGraphics();
//            int x = (target.getWidth() - source.getWidth()) / 2;
//            int y = (target.getHeight() - source.getHeight()) / 2;
//            graphics2D.drawImage(source, x, y, source.getWidth(), source.getHeight(), null);
//            graphics2D.dispose();
//            // 字节输入流
//            InputStream inputStream = ImageUtil.getInputStreamFromBufferedImage(target, "png");
//            //
//            int index;
//            byte[] bytes = new byte[1024];
//            FileOutputStream downloadFile = new FileOutputStream("D:\\target.png");
//            while ((index = inputStream.read(bytes)) != -1) {
//                downloadFile.write(bytes, 0, index);
//                downloadFile.flush();
//            }
//            downloadFile.close();
//            inputStream.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    /**
     * @Description BufferedImage 转化成 InputStream
     * @Author lixing
     * @Date 2021/7/5 16:15
     * @Param [bufferedImage] 
     * @return java.io.InputStream
     */
    public static InputStream getInputStreamFromBufferedImage(BufferedImage bufferedImage, String imageType) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ImageIO.write(bufferedImage, imageType, os);
            InputStream inputStream = new ByteArrayInputStream(os.toByteArray());
            return inputStream;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Description 图片缩放
     * @Author lixing
     * @Date 2021/7/5 13:59
     * @Param [bufferedImage 文件对象, imageType图片类型, width 最终宽度, height 最终高度, equalScale 是否等比]
     * @return java.io.InputStream
     */
    public static InputStream zoom(BufferedImage bufferedImage, String imageType, int width, int height, boolean equalScale) {
        double sx = (double) width / bufferedImage.getWidth();
        double sy = (double) height / bufferedImage.getHeight();
        // 等比缩放
        if (equalScale) {
            if (sx > sy) {
                sx = sy;
                width = (int) (sx * bufferedImage.getWidth());
            } else {
                sy = sx;
                height = (int) (sy * bufferedImage.getHeight());
            }
        }
        ColorModel cm = bufferedImage.getColorModel();
        WritableRaster raster = cm.createCompatibleWritableRaster(width, height);
        boolean alphaPremultiplied = cm.isAlphaPremultiplied();
        BufferedImage target = new BufferedImage(cm, raster, alphaPremultiplied, null);
        Graphics2D g = target.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g.drawRenderedImage(bufferedImage, AffineTransform.getScaleInstance(sx, sy));
        g.dispose();
        InputStream inputStream = ImageUtil.getInputStreamFromBufferedImage(target, imageType);
        return inputStream;
    }

    /**
     * @Description 图片合成
     * @Author lixing
     * @Date 2021/6/18 9:21
     * @Param [source 来源文件地址，target 目标文件地址, imgType 图片格式] 将source合并到target
     * @return java.io.InputStream
     */
    public static InputStream synthesis(String sourceUrl, String targetUrl, String imgType) {
        try {
            // "https://etiger.oss-cn-hangzhou.aliyuncs.com/d2902f61de0f40ad9d7ab35921a0ba3f.mp4?x-oss-process=video/snapshot,t_1000,f_jpg,w_800,h_600,m_fast"
            BufferedImage target = ImageIO.read(new URL(targetUrl));
            // "https://etiger.oss-cn-hangzhou.aliyuncs.com/module/5ca6c58bd23b0328c94f8cb4abb052c.png"
            BufferedImage source = ImageIO.read(new URL(sourceUrl));
            Graphics2D graphics2D = target.createGraphics();
            int x = (target.getWidth() - source.getWidth()) / 2;
            int y = (target.getHeight() - source.getHeight()) / 2;
            graphics2D.drawImage(source, x, y, source.getWidth(), source.getHeight(), null);
            graphics2D.dispose();
            // 字节输入流
            InputStream inputStream = ImageUtil.getInputStreamFromBufferedImage(target, imgType);
            return inputStream;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @Description 给图片添加水印文字
     * @Author lixing
     * @Date 2020/1/3 13:59
     * @Param [watermarkText 水印标题, watermarkDate 水印日期,
     *          sourceFilePath C:\Users\lixing\Desktop\水印.png,
     *          targetFilePath 格式1：C:\Users\lixing\Desktop（直接在图片上加水印） 格式2：C:\Users\lixing\Desktop\demo（重新生成加水印的图片） ]

     */
    public static void imageWatermark(String watermarkTitle, String watermarkDate, String sourceFilePath, String targetFilePath) {
        Path sourceFilePath_ = Paths.get(sourceFilePath);
        if (StrUtil.isEffective(sourceFilePath) && Files.exists(sourceFilePath_)) {
            OutputStream outputStream = null;
            try {
                // 1、源图片
                Image srcImg = ImageIO.read(sourceFilePath_.toFile());
                BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
                // 2、得到画笔对象
                Graphics2D g = buffImg.createGraphics();
                // 3、设置对线段的锯齿状边缘处理
                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);
                // 4、设置水印旋转
                if (null != DEGREE) {
                    g.rotate(Math.toRadians(DEGREE), buffImg.getWidth() / 2, buffImg.getHeight() / 2);
                }
                // 5、设置水印文字颜色
                g.setColor(MARKCONTENTCOLOR);
                // 6、设置水印文字Font
                g.setFont(new Font(FONT_FAMILY, FONT_STYLE, buffImg.getHeight() / 30));
                // 7、设置水印文字透明度
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, ALPHA));
                // 8、第一参数->设置的内容，后面两个参数->文字在图片上的坐标位置(x,y)
                g.drawString(watermarkTitle, buffImg.getWidth() / 3, (int) (buffImg.getHeight() / 2.5));
                g.drawString(watermarkDate, (int) (buffImg.getWidth() / 3), (int) (buffImg.getHeight() / 2.3));
                // 9、释放资源
                g.dispose();
                // 10、生成图片
                Map<String, String> stringMap = FileUtil.getFileNameFromAbsolutePath(sourceFilePath);
                // 图片文件类型
                String type = stringMap.get("type");
                // 图片文件名称
                String name = stringMap.get("name");
                if ( StrUtil.isEffective(targetFilePath)) {
                    FileUtil.createDirectory(targetFilePath);
                    if (targetFilePath.endsWith("\\")) {
                        targetFilePath += name;
                    } else {
                        targetFilePath += (File.separator + name);
                    }
                } else {
                    targetFilePath = sourceFilePath;
                }
                outputStream = new FileOutputStream(targetFilePath);
                // 11 生成带水印的图片文件
                ImageIO.write(buffImg, type, outputStream);
            } catch (Exception e) {
                LoggerUtil.error(MessageFormat.format("图片加水印出错：{0}", e.getMessage()));
            } finally {
                try {
                    if (null != outputStream) {
                        outputStream.close();
                    }
                } catch (Exception e) {
                    LoggerUtil.error(MessageFormat.format("图片加水印结束，关闭输出流出错：{0}", e.getMessage()));
                }
            }
        } else {
            throw new BaseException(MessageFormat.format("目标文件：{0} 不存在", sourceFilePath));
        }
    }

}